package top.broncho.lottery.ui.widget

import android.graphics.Canvas
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.view.View
import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.RecyclerView

/**
 * Item decoration which draws item divider between each items.
 */
class SimpleListDividerDecorator(
    private val horizontalDrawable: Drawable?,
    private val verticalDrawable: Drawable?,
    private val isOverlap: Boolean
) : RecyclerView.ItemDecoration() {
    private val horizontalDividerHeight: Int = horizontalDrawable?.intrinsicHeight ?: 0
    private val verticalDividerWidth: Int = verticalDrawable?.intrinsicWidth ?: 0

    override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        val childCount = parent.childCount


        if (childCount == 0) {
            return
        }

        val xPositionThreshold = if (isOverlap) 1.0f else verticalDividerWidth + 1.0f // [px]
        val yPositionThreshold = if (isOverlap) 1.0f else horizontalDividerHeight + 1.0f // [px]
        val zPositionThreshold = 1.0f // [px]

        for (i in 0 until childCount - 1) {
            val child = parent.getChildAt(i)
            val nextChild = parent.getChildAt(i + 1)

            if (child.visibility != View.VISIBLE || nextChild.visibility != View.VISIBLE) {
                continue
            }

            // check if the next item is placed at the bottom or right
            val childBottom = child.bottom + child.translationY
            val nextChildTop = nextChild.top + nextChild.translationY
            val childRight = child.right + child.translationX
            val nextChildLeft = nextChild.left + nextChild.translationX

            if (!(horizontalDividerHeight != 0 && Math.abs(nextChildTop - childBottom) < yPositionThreshold || verticalDividerWidth != 0 && Math.abs(
                    nextChildLeft - childRight
                ) < xPositionThreshold)
            ) {
                continue
            }

            // check if the next item is placed on the same plane
            val childZ = ViewCompat.getTranslationZ(child) + ViewCompat.getElevation(child)
            val nextChildZ =
                ViewCompat.getTranslationZ(nextChild) + ViewCompat.getElevation(nextChild)

            if (Math.abs(nextChildZ - childZ) >= zPositionThreshold) {
                continue
            }

            val childAlpha = child.alpha
            val nextChildAlpha = nextChild.alpha

            val tx = (child.translationX + 0.5f).toInt()
            val ty = (child.translationY + 0.5f).toInt()

            if (horizontalDividerHeight != 0) {
                val left = child.left
                val right = child.right
                val top = child.bottom - if (isOverlap) horizontalDividerHeight else 0
                val bottom = top + horizontalDividerHeight

                horizontalDrawable!!.alpha =
                    (0.5f * 255 * (childAlpha + nextChildAlpha) + 0.5f).toInt()
                horizontalDrawable.setBounds(left + tx, top + ty, right + tx, bottom + ty)
                horizontalDrawable.draw(c)
            }

            if (verticalDividerWidth != 0) {
                val left = child.right - if (isOverlap) verticalDividerWidth else 0
                val right = left + verticalDividerWidth
                val top = child.top
                val bottom = child.bottom

                verticalDrawable!!.alpha =
                    (0.5f * 255 * (childAlpha + nextChildAlpha) + 0.5f).toInt()
                verticalDrawable.setBounds(left + tx, top + ty, right + tx, bottom + ty)
                verticalDrawable.draw(c)
            }
        }
    }

    override fun getItemOffsets(
        outRect: Rect,
        view: View,
        parent: RecyclerView,
        state: RecyclerView.State
    ) {
        if (isOverlap) {
            outRect.set(0, 0, 0, 0)
        } else {
            outRect.set(0, 0, verticalDividerWidth, horizontalDividerHeight)
        }
    }
}
